package naga.x.net;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import gnu.trove.map.TShortObjectMap;
import gnu.trove.map.hash.TShortObjectHashMap;

public class PacketDispatcher implements PacketHandler {

	protected static final Logger LOG = LoggerFactory.getLogger(PacketDispatcher.class);
	
	protected TShortObjectMap<PacketHandler> handlers = new TShortObjectHashMap<PacketHandler>(128);
	protected List<PacketFilter> filters = new CopyOnWriteArrayList<PacketFilter>();
	
	@Override
	public void handle(Session session, Packet packet) {
		int size;
		if ((size = filters.size()) > 0) {
			for (int i = 0; i < size; i++) {
				if (!filters.get(i).filter(session, packet)) {
					LOG.info("[PACKET FILTER]SESSION[" + session.getId() + "]PACKET[" + packet.getOpCode() + "]");
					return;
				}
			}
		}
		PacketHandler handler = handlers.get(packet.getOpCode());
		if (handler != null) {
			try {
				handler.handle(session, packet);
			} catch (Exception e) {
				LOG.error(e.getMessage(), e);
			}
		}
	}
	
	public void register(short code, PacketHandler handler) {
		handlers.put(code, handler);
	}
	
	public void unRegister(short code) {
		handlers.remove(code);
	}
	
	public void addFilter(PacketFilter filter) {
		filters.add(filter);
	}
	
	public void removeFilter(PacketFilter filter) {
		filters.remove(filter);
	}

}
